package com.xuecheng.content.service.jobhandler;

import com.alibaba.fastjson.JSON;
import com.xuecheng.content.feignclient.search.CourseIndex;
import com.xuecheng.content.feignclient.search.CourseIndexClient;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.content.service.CoursePublishService;
import com.xuecheng.messagesdk.model.po.MqMessage;
import com.xuecheng.messagesdk.service.MessageProcessAbstract;
import com.xuecheng.messagesdk.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * 课程发布后续任务类
 */
@Slf4j
@Component
public class CoursePublishTask extends MessageProcessAbstract {
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    CoursePublishService coursePublishService;

    @Autowired
    CourseIndexClient courseIndexClient;

    @XxlJob("coursePublishTask")
    public void coursePublishTask(){
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        log.info("课程发布后续数据同步任务开始执行，当前分片序号：{}，分片总数：{}",shardIndex,shardTotal);
        process(shardIndex,shardTotal,"course_publish",30,60);
        log.info("课程发布后续数据同步任务结束，当前分片序号：{}，分片总数：{}",shardIndex,shardTotal);
    }

    /**
     * 多线程核心任务，此处是课程发布后续数据同步任务
     * @param mqMessage
     * @return
     */
    @Override
    public boolean execute(MqMessage mqMessage) {
        //这个数据同步任务分3个阶段：页面静态化、课程发布数据写入es、课程发布数据写入redis
        //获取业务相关信息
        Long courseId = Long.parseLong(mqMessage.getBusinessKey1());

        //1.页面静态化
        boolean state1 = generateCourseHtml(mqMessage,courseId);

        //2.课程发布数据写入es，保存课程索引
        boolean state2 = saveCourseIndex(mqMessage,courseId);

        //3.课程发布数据写入redis，保存课程缓存
        boolean state3 = saveCourseCache(mqMessage,courseId);

        return state1 && state2 && state3;
//        return state3;
    }

    /**
     * 页面静态化
     * @param mqMessage
     * @param courseId
     * @return
     */
    private boolean generateCourseHtml(MqMessage mqMessage, Long courseId) {
        log.info("开始进行课程页面静态化，课程id:{}",courseId);
        //消息id
        Long id = mqMessage.getId();
        //这里要重新查一下阶段状态，不能直接用mqMessage，因为高并发情况下，当前的mqMessage
        //的状态没有被修改，但是数据库里面可能已经更新了，所以要查数据库最新的
        int stage1 = mqMessageService.getStageOne(id);
        if(stage1 > 0){
            log.info("课程静态化已处理，直接返回，课程id：{}",courseId);
            return true;
        }
        try{
            //课程静态化
            File file = coursePublishService.generateCourseHtml(courseId);
            coursePublishService.uploadCourseHtml(courseId,file);
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
        //保存第一阶段状态
        mqMessageService.completedStageOne(id);
        return true;
    }

    /**
     * 保存课程索引
     * @param mqMessage
     * @param courseId
     * @return
     */
    private boolean saveCourseIndex(MqMessage mqMessage, Long courseId) {
        log.info("开始保存课程索引信息，课程id:{}",courseId);
        //消息id
        Long id = mqMessage.getId();
        int stage2 = mqMessageService.getStageTwo(id);
        if(stage2 > 0){
            log.info("保存课程索引信息已处理，直接返回，课程id：{}",courseId);
            return true;
        }
        try{
            //保存课程索引信息
            //首先将课程发布信息查出来
            CoursePublish coursePublish = coursePublishService.getById(courseId);
            CourseIndex courseIndex = new CourseIndex();
            BeanUtils.copyProperties(coursePublish,courseIndex);
            Boolean add = courseIndexClient.add(courseIndex);
            if(!add) return false;
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
        //保存第二阶段状态
        mqMessageService.completedStageTwo(id);
        return true;
    }

    /**
     * 保存课程缓存
     * @param mqMessage
     * @param courseId
     * @return
     */
    private boolean saveCourseCache(MqMessage mqMessage, Long courseId) {
        log.info("将课程信息缓存至redis，课程id:{}",courseId);
        //消息id
        Long id = mqMessage.getId();
        int stage3 = mqMessageService.getStageThree(id);
        if(stage3 > 0){
            log.info("保存课程缓存已处理，直接返回，课程id：{}",courseId);
            return true;
        }
        try{
            //保存课程缓存
            //先将课程发布信息查询出来
            CoursePublish coursePublish = coursePublishService.getById(courseId);
            stringRedisTemplate.opsForValue().set("content:course:publish:" + courseId,
                    JSON.toJSONString(coursePublish));
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
        //保存第三阶段状态
        mqMessageService.completedStageThree(id);
//        return true;
        return false;
    }
}
